//
// Created by 郝羽 on 2018/6/20.
//

#include "metric_client.hpp"

#include <arpa/inet.h>
#include <glib.h>
#include <gio/gio.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <sys/socket.h>

#include "metric.hpp"

struct MetricClient {
    const char* address;
    int fd;
};

MetricClient *metric_client_open(const char* address) {
    auto c = new MetricClient();

    c->address = address;

    GSocketClient* sock = g_socket_client_new();

    GError* err = nullptr;

    GSocketConnection* conn = g_socket_client_connect_to_host(sock, c->address,
            0, nullptr, &err);

    if (err != nullptr) {
        g_warning("child: %d connect metric server '%s' error: %s", getpid(),
                c->address, err->message);
        exit(-1);
    }

    c->fd = g_socket_get_fd(g_socket_connection_get_socket(conn));

    return c;
}

void metric_client_close(MetricClient *c) {
    delete(c);
}

void metric_client_send_metric(MetricClient* c, Metric &metric) {
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();
    writer.Key("time");
    writer.Int64(metric.time);
    if (metric.rtt.Samples().size() > 0) {
        writer.Key("rtt");
        writer.StartArray();
        for (auto sample : metric.rtt.Samples()) {
            writer.Int(sample);
        }
        writer.EndArray();
    }

    if (metric.jitter.Samples().size() > 0) {
        writer.Key("jitter");
        writer.StartArray();
        for (auto sample : metric.jitter.Samples()) {
            writer.Int(sample);
        }
        writer.EndArray();
    }

    if (metric.setup_time.Samples().size() > 0) {
        writer.Key("setup-time");
        writer.StartArray();
        for (auto sample : metric.setup_time.Samples()) {
            writer.Int(sample);
        }
        writer.EndArray();
    }

    if (metric.inited.Get()) {
        writer.Key("inited");
        writer.Int(metric.inited.Get().Get());
    }
    if (metric.setup.Get()) {
        writer.Key("setup");
        writer.Int(metric.setup.Get().Get());
    }
    if (metric.send.Get()) {
        writer.Key("send");
        writer.Int64(metric.send.Get().Get());
    }
    if (metric.recv.Get()) {
        writer.Key("recv");
        writer.Int64(metric.recv.Get().Get());
    }
    if (metric.send_packet.Get()) {
        writer.Key("send-pkts");
        writer.Int64(metric.send_packet.Get().Get());
    }
    if (metric.recv_packet.Get()) {
        writer.Key("recv-pkts");
        writer.Int64(metric.recv_packet.Get().Get());
    }

    if (metric.ping_time.Samples().size() > 0) {
        writer.Key("ping-time");
        writer.StartArray();
        for (auto sample : metric.ping_time.Samples()) {
            writer.Int(sample);
        }
        writer.EndArray();
    }

    writer.EndObject();

    g_message("child: %d %s", getpid(), buffer.GetString());

    int l = buffer.GetSize();

    l = ntohl(l);

    // todo: 让这两个发送异步
    send(c->fd, &l, 4, 0);
    send(c->fd, buffer.GetString(), buffer.GetSize(), 0);
}